﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using Speakup;
using System.Globalization;
using System.Windows.Media;
using System.Windows.Controls.Primitives;

namespace SpeakupUI
{
    class TodoPanel: ContentControl 
    {
        List<Class> DoneClassList = new List<Class>();
        ClassPanelList ClassPanelList;

        Grid ReservationsGrid;
        Grid CancellationsGrid;

        public TodoPanel(ClassPanelList list)
        {
            ClassPanelList = list;

            ReservationsGrid = new Grid();
            CancellationsGrid = new Grid();

            GroupBox ReservationsBox = new GroupBox();
            ReservationsBox.Header = "Classes you wanted to reserve!";
            ReservationsBox.Content = ReservationsGrid;


            GroupBox CancellationsBox = new GroupBox();
            CancellationsBox.Header = "Classes you wanted to cancel!";
            CancellationsBox.Content = CancellationsGrid;

            StackPanel panel = new StackPanel();
            panel.Children.Add(ReservationsBox);
            panel.Children.Add(CancellationsBox);


            ScrollViewer viewer = new ScrollViewer();
            viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            viewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            
            viewer.Content = panel;

            Content = viewer;

            RefreshReservations();
        }

        public void Refresh()
        {
            RefreshReservations();
            RefreshCancellations();
        }

        public void RefreshReservations()
        {
            ReservationsGrid.HorizontalAlignment = HorizontalAlignment.Center;
            ReservationsGrid.Children.Clear();
            ReservationsGrid.RowDefinitions.Clear();
            ReservationsGrid.ColumnDefinitions.Clear();
            ReservationsGrid.ShowGridLines = true;
            
            ColumnDefinition coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            ReservationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            ReservationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            ReservationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            ReservationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            ReservationsGrid.ColumnDefinitions.Add(coldef);
            
            ReservationsGrid.RowDefinitions.Add(new RowDefinition());

            Label nameLabel = new Label();
            nameLabel.VerticalAlignment = VerticalAlignment.Center;
            nameLabel.HorizontalAlignment = HorizontalAlignment.Center;
            
            nameLabel.Content = "class";
            ReservationsGrid.Children.Add(nameLabel);
            Grid.SetColumn(nameLabel,0);
            Grid.SetRow(nameLabel,0);

            Label dateLabel = new Label();
            dateLabel.VerticalAlignment = VerticalAlignment.Center;
            dateLabel.HorizontalAlignment = HorizontalAlignment.Center;            

            dateLabel.Content = "date";
            ReservationsGrid.Children.Add(dateLabel);
            Grid.SetColumn(dateLabel,1);
            Grid.SetRow(dateLabel,0);

            Label availableLabel = new Label();
            availableLabel.VerticalAlignment = VerticalAlignment.Center;
            availableLabel.HorizontalAlignment = HorizontalAlignment.Center;
            

            availableLabel.Content = "available";
            ReservationsGrid.Children.Add(availableLabel);
            Grid.SetColumn(availableLabel,2);
            Grid.SetRow(availableLabel,0);

            Label doneLabel = new Label();
            doneLabel.VerticalAlignment = VerticalAlignment.Center;
            doneLabel.HorizontalAlignment = HorizontalAlignment.Center;
            doneLabel.Content = "Reserved?";
            ReservationsGrid.Children.Add(doneLabel);
            Grid.SetColumn(doneLabel,3);
            Grid.SetRow(doneLabel,0);

            Label undoLabel = new Label();
            undoLabel.VerticalAlignment = VerticalAlignment.Center;
            undoLabel.HorizontalAlignment = HorizontalAlignment.Center;
            undoLabel.Content = "Changed you mind?";
            ReservationsGrid.Children.Add(undoLabel);
            Grid.SetColumn(undoLabel,4);
            Grid.SetRow(undoLabel, 0);

            
            foreach (ClassPanel panel in ClassPanelList.Panels)
            {
                Class speakupClass = panel.SpeakupClass;
                if (speakupClass.Modified)
                {
                    if (speakupClass.PreviousStatus == ClassStatus.Available ||
                        speakupClass.PreviousStatus == ClassStatus.AvailableWaitList)
                    {
                        AddReservation(speakupClass);
                    }
                }
            }

            if (ReservationsGrid.RowDefinitions.Count <= 1)
            {
                ReservationsGrid.RowDefinitions.Clear();
                ReservationsGrid.Children.Clear();
                Label lbl = new Label();
                lbl.Content = "No items where marked for reservation";
                ReservationsGrid.Children.Add(lbl);
                ReservationsGrid.ShowGridLines = false;
            }

        }

        public void RefreshCancellations()
        {
            CancellationsGrid.HorizontalAlignment = HorizontalAlignment.Center;
            CancellationsGrid.Children.Clear();
            CancellationsGrid.RowDefinitions.Clear();
            CancellationsGrid.ColumnDefinitions.Clear();
            CancellationsGrid.ShowGridLines = true;

            ColumnDefinition coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            CancellationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            CancellationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            CancellationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            CancellationsGrid.ColumnDefinitions.Add(coldef);

            coldef = new ColumnDefinition();
            coldef.Width = GridLength.Auto;
            CancellationsGrid.ColumnDefinitions.Add(coldef);

            CancellationsGrid.RowDefinitions.Add(new RowDefinition());

            Label nameLabel = new Label();
            nameLabel.VerticalAlignment = VerticalAlignment.Center;
            nameLabel.HorizontalAlignment = HorizontalAlignment.Center;

            nameLabel.Content = "class";
            CancellationsGrid.Children.Add(nameLabel);
            Grid.SetColumn(nameLabel, 0);
            Grid.SetRow(nameLabel, 0);

            Label dateLabel = new Label();
            dateLabel.VerticalAlignment = VerticalAlignment.Center;
            dateLabel.HorizontalAlignment = HorizontalAlignment.Center;

            dateLabel.Content = "date";
            CancellationsGrid.Children.Add(dateLabel);
            Grid.SetColumn(dateLabel, 1);
            Grid.SetRow(dateLabel, 0);

            Label availableLabel = new Label();
            availableLabel.VerticalAlignment = VerticalAlignment.Center;
            availableLabel.HorizontalAlignment = HorizontalAlignment.Center;
                       

            Label doneLabel = new Label();
            doneLabel.VerticalAlignment = VerticalAlignment.Center;
            doneLabel.HorizontalAlignment = HorizontalAlignment.Center;

            doneLabel.Content = "Cancelled?";
            CancellationsGrid.Children.Add(doneLabel);
            Grid.SetColumn(doneLabel, 2);
            Grid.SetRow(doneLabel, 0);

            Label undoLabel = new Label();
            undoLabel.VerticalAlignment = VerticalAlignment.Center;
            undoLabel.HorizontalAlignment = HorizontalAlignment.Center;

            undoLabel.Content = "Changed you mind?";
            CancellationsGrid.Children.Add(undoLabel);
            Grid.SetColumn(undoLabel, 3);
            Grid.SetRow(undoLabel, 0);


            foreach (ClassPanel panel in ClassPanelList.Panels)
            {
                Class speakupClass = panel.SpeakupClass;
                if (speakupClass.Modified)
                {
                    if (speakupClass.PreviousStatus == ClassStatus.Reserved ||
                        speakupClass.PreviousStatus == ClassStatus.ReservedWaitList)
                    {
                        AddCancellation(speakupClass);
                    }
                }
            }

            if (CancellationsGrid.RowDefinitions.Count <= 1)
            {
                CancellationsGrid.RowDefinitions.Clear();
                CancellationsGrid.Children.Clear();
                Label lbl = new Label();
                lbl.Content = "No items where marked for cancellation.";
                CancellationsGrid.Children.Add(lbl);
                CancellationsGrid.ShowGridLines = false;
            }

        }

        void AddReservation(Class speakupClass)
        {
            int row = ReservationsGrid.RowDefinitions.Count;
            ReservationsGrid.RowDefinitions.Add(new RowDefinition());

            Button undoButton = null;
            Label availableLabel = null;
            Label dateLabel = null;
            Label nameLabel = null;

            {
                nameLabel = new Label();
                nameLabel.VerticalAlignment = VerticalAlignment.Center;
                nameLabel.HorizontalAlignment = HorizontalAlignment.Center;
                nameLabel.Padding = new Thickness(5);

                nameLabel.Content = speakupClass.ClassName.FullName;
                ReservationsGrid.Children.Add(nameLabel);
                Grid.SetRow(nameLabel, row);
                Grid.SetColumn(nameLabel, 0);
            }

            {
                string strDate = speakupClass.ClassTime.Date.ToString("MMM dd yyyy",CultureInfo.InvariantCulture);
                TimeSlot slot = new TimeSlot(speakupClass.ClassTime.Begin, speakupClass.ClassTime.End);

                string strTime = slot.ToString();
                string dateTitle = strDate + "\n" + strTime;

                dateLabel = new Label();
                dateLabel.VerticalAlignment = VerticalAlignment.Center;
                dateLabel.HorizontalAlignment = HorizontalAlignment.Center;
                dateLabel.Padding = new Thickness(50,5,50,5);


                dateLabel.Content = dateTitle;
                ReservationsGrid.Children.Add(dateLabel);
                Grid.SetRow(dateLabel, row);
                Grid.SetColumn(dateLabel, 1);
            }

            {
                availableLabel = new Label();
                availableLabel.VerticalAlignment = VerticalAlignment.Center;
                availableLabel.HorizontalAlignment = HorizontalAlignment.Center;
                availableLabel.Padding = new Thickness(50, 5, 50, 5);


                availableLabel.Content = speakupClass.PreviousStatus == ClassStatus.Available ? 
                                        "yes" : 
                                        "Only for a waiting list";

                ReservationsGrid.Children.Add(availableLabel);
                Grid.SetRow(availableLabel, row);
                Grid.SetColumn(availableLabel, 2);
            }                   
          
            {
                undoButton = new Button();
                undoButton.VerticalAlignment = VerticalAlignment.Center;
                undoButton.HorizontalAlignment = HorizontalAlignment.Center;
                undoButton.Padding = new Thickness(3);
                undoButton.Margin = new Thickness(5);

                undoButton.Content = "Remove from this list.";
                ReservationsGrid.Children.Add(undoButton);
                Grid.SetRow(undoButton, row);
                Grid.SetColumn(undoButton, 4);

                undoButton.Click += delegate
                {
                    speakupClass.CancelModification();
                    RefreshReservations();
                };
            }

            {
                ToggleButton doneButton = new ToggleButton();
                doneButton.VerticalAlignment = VerticalAlignment.Center;
                doneButton.HorizontalAlignment = HorizontalAlignment.Center;
                doneButton.Padding = new Thickness(3);
                doneButton.Margin = new Thickness(5);

                doneButton.Content = "I reserved this class.";
                ReservationsGrid.Children.Add(doneButton);
                Grid.SetRow(doneButton, row);
                Grid.SetColumn(doneButton, 3);

                doneButton.Checked += delegate
                {
                    undoButton.IsEnabled = false;
                    nameLabel.IsEnabled = false;
                    nameLabel.Foreground = Brushes.LightGray;

                    dateLabel.IsEnabled = false;
                    dateLabel.Foreground = Brushes.LightGray;

                    availableLabel.IsEnabled = false;
                    availableLabel.Foreground = Brushes.LightGray;

                    if (!DoneClassList.Contains(speakupClass))
                    {
                        DoneClassList.Add(speakupClass);
                    }
                };

                doneButton.Unchecked += delegate
                {
                    undoButton.IsEnabled = true;
                    nameLabel.IsEnabled = true;
                    nameLabel.Foreground = Brushes.Black;

                    dateLabel.IsEnabled = true;
                    dateLabel.Foreground = Brushes.Black;

                    availableLabel.IsEnabled = true;
                    availableLabel.Foreground = Brushes.Black;

                    if (DoneClassList.Contains(speakupClass))
                    {
                        DoneClassList.Remove(speakupClass);
                    }
                };

                doneButton.IsChecked = DoneClassList.Contains(speakupClass);
            }
        }

        void AddCancellation(Class speakupClass)
        {
            int row = CancellationsGrid.RowDefinitions.Count;
            CancellationsGrid.RowDefinitions.Add(new RowDefinition());

            Button undoButton = null;            
            Label dateLabel = null;
            Label nameLabel = null;

            {
                nameLabel = new Label();
                nameLabel.VerticalAlignment = VerticalAlignment.Center;
                nameLabel.HorizontalAlignment = HorizontalAlignment.Center;
                nameLabel.Padding = new Thickness(5);

                nameLabel.Content = speakupClass.ClassName.FullName;
                CancellationsGrid.Children.Add(nameLabel);
                Grid.SetRow(nameLabel, row);
                Grid.SetColumn(nameLabel, 0);
            }

            {
                string strDate = speakupClass.ClassTime.Date.ToString("MMM dd yyyy", CultureInfo.InvariantCulture);
                TimeSlot slot = new TimeSlot(speakupClass.ClassTime.Begin, speakupClass.ClassTime.End);

                string strTime = slot.ToString();
                string dateTitle = strDate + "\n" + strTime;

                dateLabel = new Label();
                dateLabel.VerticalAlignment = VerticalAlignment.Center;
                dateLabel.HorizontalAlignment = HorizontalAlignment.Center;
                dateLabel.Padding = new Thickness(50, 5, 50, 5);


                dateLabel.Content = dateTitle;
                CancellationsGrid.Children.Add(dateLabel);
                Grid.SetRow(dateLabel, row);
                Grid.SetColumn(dateLabel, 1);
            }

            {
                undoButton = new Button();
                undoButton.VerticalAlignment = VerticalAlignment.Center;
                undoButton.HorizontalAlignment = HorizontalAlignment.Center;
                undoButton.Padding = new Thickness(3);
                undoButton.Margin = new Thickness(5);

                undoButton.Content = "Remove from this list.";
                CancellationsGrid.Children.Add(undoButton);
                Grid.SetRow(undoButton, row);
                Grid.SetColumn(undoButton, 3);

                undoButton.Click += delegate
                {
                    speakupClass.CancelModification();
                    RefreshCancellations();
                };
            }

            {
                ToggleButton doneButton = new ToggleButton();
                doneButton.VerticalAlignment = VerticalAlignment.Center;
                doneButton.HorizontalAlignment = HorizontalAlignment.Center;
                doneButton.Padding = new Thickness(3);
                doneButton.Margin = new Thickness(5);

                doneButton.Content = "I cancelled this class.";
                CancellationsGrid.Children.Add(doneButton);
                Grid.SetRow(doneButton, row);
                Grid.SetColumn(doneButton, 2);

                doneButton.Checked += delegate
                {
                    undoButton.IsEnabled = false;
                    nameLabel.IsEnabled = false;
                    nameLabel.Foreground = Brushes.LightGray;

                    dateLabel.IsEnabled = false;
                    dateLabel.Foreground = Brushes.LightGray;

                    if (!DoneClassList.Contains(speakupClass))
                    {
                        DoneClassList.Add(speakupClass);
                    }
                };

                doneButton.Unchecked += delegate
                {
                    undoButton.IsEnabled = true;
                    nameLabel.IsEnabled = true;
                    nameLabel.Foreground = Brushes.Black;

                    dateLabel.IsEnabled = true;
                    dateLabel.Foreground = Brushes.Black;

                    if (DoneClassList.Contains(speakupClass))
                    {
                        DoneClassList.Remove(speakupClass);
                    }
                    
                };
            }
        }
    }
}
